package package1;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;

/**
 * attention: CMD cannot recognize space(" ") in the command so we put \" around
 * the file path remove the package message for easy usage, if you keep package,
 * need create hierarchy folders in jar file important: when using
 * BufferedInputStream(with byte[] as buffer), it does not destroy class file
 * when creating jar file, please mark running method note: debug log would have
 * suffer the multi-thread issue to have a messy output
 * 
 * @author Alvin.Wang
 */
public class AutoPackEverydayOld {
	public static String DESKTOP = "";
	public static String WORKSPACE = "";
	public static String JARLOCATION = "";
	public static String PROJECTNAME = "JavaLearning";
	public static String PACKAGENAME = "package1";
	public static String className = getClassName();
	public static String ZIPLOG = "";
	public static String HOME = "HOME";
	public static String OFFICE = "OFFICE";
	public static String PLACE = "";
	public static boolean testBat = false;
	public static boolean showDebugLog = false;
	public static String archiveFolderName = "JAVA ARCHIVE";
	public static String BOOTPATH = "";
	public static String JRE = "JRE";
	public static String JDK = "JDK";

	public static void main(String[] args) throws Exception {
		//attention: plz don't change the name of the method or it might break down
		initializingParameters();
		createJarFileInLocationFolder();
		// runJavaFileForAutoPackEveryday();
		
		//for user
		//1. put the install file into destination folder
		//2. double click to install by creating jar file in appointed location and shortcut in desktop and meanwhile delete the install file
		//3. trying start the shortcut to test if the destination folder has been packed on desktop
		
		//for programmer
		//1. 
		//1. packing function with parameters
//			 packing function packed in jar and put in jar location
		//2. 
		//3. 
	}

	
	private static void createInstallJar() {
		
	}


	private static void initializingParameters() throws Exception {
		
		if (PLACE == HOME) {
			DESKTOP = "C:\\Users\\Alvin\\Desktop";
			WORKSPACE = "D:\\Program Files\\Java\\WorkSpace";
			JARLOCATION = "D:\\Program Files\\Java\\jar scripts";
		} else if (PLACE == OFFICE) {
			DESKTOP = "c:\\users\\alvin.wang\\desktop";
			WORKSPACE = "D:\\Program Files\\workspace";
			JARLOCATION = "D:\\Program Files\\eclipse\\jar scripts";
		}
		ZIPLOG = WORKSPACE + "\\" + PROJECTNAME + "\\src";

		StringBuffer sb = new StringBuffer();
		Map<Object, Object> map = System.getProperties();
		int max = 0;
		int b = 0;
		for (Object a : map.keySet()) {// get max length of character
			b = a.toString().trim().length();
			if (max < b)
				max = b;
		}
		for (Object a : map.keySet()) {
			String temp = addSpace(a.toString().trim(), max + 1) + "\t#\t" + map.get(a).toString().trim() + "\r\n";
			sb.append(temp);
		}
		writeToFile("filepath.txt", sb.toString());
	}

	private static String addSpace(String str, int s) {
		int times = s - str.length();
		StringBuffer sb = new StringBuffer(str);
		for (int i = 0; i < times; i++) {
			sb.append(" ");
		}
		return sb.toString();
	}

	/**
	 * attention: when creating javaFile, we will mark "create" method and
	 * unmark "run" method
	 * 
	 * @throws Exception
	 */
	private static void createJarFileInLocationFolder() throws Exception {

		// copy Java File and do some hack
		File javaFile = new File(className + ".java");
		String javaFilePath = getJavaFilePath();
		BufferedReader br = new BufferedReader(new FileReader(new File(javaFilePath)));
		BufferedWriter bw = new BufferedWriter(new FileWriter(javaFile));
		String buf;
		while ((buf = br.readLine()) != null) {
			if (buf.contains("package " + PACKAGENAME + ";") && !buf.contains("if"))
				buf = "";
			if (buf.contains("createJarFileInLocationFolder();") && !buf.contains("if"))
				buf = "//" + buf;
			if (buf.contains("runJavaFileForAutoPackEveryday();") && !buf.contains("if"))
				buf = removeMark(buf);
			bw.write(buf);
			bw.newLine();
		}
		bw.close();
		br.close();

		// compileJavaClass
		String cmd = "javac " + quoteAddressForCMD(javaFile.getAbsolutePath());
		run(cmd);

		// create mf file
		File mf = new File("manifest.mf");
		bw = new BufferedWriter(new FileWriter(mf));
		bw.write("Main-Class: " + className + "\r\n");
		bw.close();

		// pack into jar file and place in the scripts location
		File classFile = new File(className + ".class");
		cmd = "jar vcfm " + quoteAddressForCMD(JARLOCATION + "\\" + className + ".jar") + " "
				+ quoteAddressForCMD(mf.getAbsolutePath()) + " " + classFile.getPath() + " " + javaFile.getName();
		run(cmd);

		// delete java, class and mf file
		javaFile.delete();
		classFile.delete();
		mf.delete();

		// create auto pack bat file
		File batFile = new File(DESKTOP + "\\" + className + ".bat");
		bw = new BufferedWriter(new FileWriter(batFile));
		cmd = "java -jar " + quoteAddressForCMD(JARLOCATION + "\\" + className + ".jar");
		bw.write(cmd);
		bw.close();

		// test
		if (testBat)
			run(batFile.getAbsolutePath());
		System.err.println("End of the program.");
	}

	private static String getJavaFilePath() throws IOException {
		String a = System.getProperty("user.dir");
		// D:\Program Files\Java\WorkSpace\JavaLearning
		String b = Thread.currentThread().getStackTrace()[1].getClassName();
		// package1.AutoPackEveryday
		b = b.replace(".", "\\");
		return a + "\\src" + "\\" + b + ".java";
	}

	public static String extractText(String str, String t1, String t2) {
		int t1Index = str.indexOf(t1);
		int t2Index = str.indexOf(t2);
		int t1Len = t1.length();
		return str.substring(t1Index + t1Len, t2Index);
	}

	/**
	 * add '"' surround the path so CMD could recognize
	 * 
	 * @param string
	 * @return
	 */
	private static String quoteAddressForCMD(String string) {
		return "\"" + string + "\"";
	}

	/**
	 * remove the mark for some code //public void to make it available
	 * 
	 * @param buf
	 * @return
	 */
	private static String removeMark(String buf) {
		String mark = "//";
		int b = buf.indexOf(mark);
		String c = buf.substring(b + mark.length(), buf.length()).trim();
		return "\t\t" + c;
	}

	/**
	 * 1. open in eclipse: package1.AutoPackEveryday.java 2. open in cmd in
	 * desktop: AutoPackEveryday.java
	 * 
	 * @return
	 */
	private static String getClassName() {
		String a = Thread.currentThread().getStackTrace()[1].getClassName();
		int b = a.indexOf(".");
		String c = a.substring(b + 1, a.length());
		return c;
	}

	@SuppressWarnings("unused")
	private static void runJavaFileForAutoPackEveryday() throws Exception {
		// copy java files into a temporary folder
		File tempFolder = new File(archiveFolderName);
		if (!tempFolder.exists())
			tempFolder.mkdirs();
		String javafileAddr = ZIPLOG + "\\" + PACKAGENAME;
		File[] javaFiles = new File(javafileAddr).listFiles();
		for (File f : javaFiles)
			copyFile(f.getParent(), tempFolder.getAbsolutePath(), f.getName());

		// pack java files in the temporary folder
		String srcAddr = quoteAddressForCMD(tempFolder.getName());
		String desktopAddr = quoteAddressForCMD(DESKTOP + "\\AutoPackEveryday.zip");
		String cmd = "jar vcf " + desktopAddr + " " + srcAddr;
		run(cmd);

		// delete the temporary folder
		deleteFolder(tempFolder.getAbsolutePath());
		if (showDebugLog) {
			String currentJavaFilePath = getJavaFilePath();
			File a = new File("a.txt");
			String b = a.getAbsolutePath();
			String c = new File(b).getParent();
			String log = "javafileAddr:" + javafileAddr + "\r\n" + "srcAddr:" + srcAddr + "\r\n" + "desktopAddr:"
					+ desktopAddr + "\r\n" + "cmd:" + cmd + "\r\n";
			log += "\r\ncurrentJavaFilePath:" + currentJavaFilePath + "\r\ncurrentparentpath:" + c;
			writeToFile(DESKTOP + "\\running log.txt", log);
		}
	}

	private static void deleteFolder(String name) {
		File folder = new File(name);
		for (File f : folder.listFiles())
			if (f.isFile())
				f.delete();
			else
				deleteFolder(f.getAbsolutePath());
		folder.delete();
	}

	private static void copyFile(String from, String to, String fileName) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(new File(from + "\\" + fileName)));
		BufferedWriter bw = new BufferedWriter(new FileWriter(new File(to + "\\" + fileName)));
		String buf;
		while ((buf = br.readLine()) != null)
			bw.write(buf + "\r\n");
		br.close();
		bw.close();
	}

	private static void run(String string) throws IOException {
		Process p = Runtime.getRuntime().exec(string);
		InputStream is1 = p.getInputStream();
		InputStream is2 = p.getErrorStream();
		BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));
		BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
		String b1, b2;
		StringBuffer sb1 = new StringBuffer();
		StringBuffer sb2 = new StringBuffer();
		while ((b1 = br1.readLine()) != null)
			sb1.append(b1 + "\r\n");
		while ((b2 = br2.readLine()) != null)
			sb2.append(b2 + "\r\n");
		br1.close();
		br2.close();
		b1 = ("Process inputStream message:\r\n" + sb1.toString()).trim();
		b2 = ("Process errorStream message:\r\n" + sb2.toString()).trim();
		if (!sb1.toString().equals("") && showDebugLog) {
			System.err.println("Process inputStream message:\r\n" + sb1.toString().trim());
			writeToFile(DESKTOP + "\\InputStream.txt", b1);
		}
		if (!sb2.toString().equals("") && showDebugLog) {
			System.err.println("Process errorStream message:\r\n" + sb2.toString().trim());
			writeToFile(DESKTOP + "\\ErrorStream.txt", b2);
		}
	}

	private static void writeToFile(String fileName, String str) throws IOException {
		File f = new File(DESKTOP + "\\" + new File(fileName).getName());
		System.err.println("writeToFilepath:" + DESKTOP + "\\" + new File(fileName).getName());
		BufferedWriter bw = new BufferedWriter(new FileWriter(f));
		bw.write(str);
		bw.close();
	}

	public static void openCurrentFolder() throws IOException {
		open(getCurrentFolder());
	}

	private static String getCurrentFolder() {
		return System.getProperty("user.dir");
	}

	private static void open(String f1) throws IOException {
		open(new File(f1));
	}
	private static void open(File file) throws IOException {
		java.awt.Desktop.getDesktop().open(file);
	}

	private static String getDesktop() {
		return System.getenv("USERPROFILE") + "\\desktop";
	}
}
